#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
int main(int argc, char** argv){
    // 1.
    cv::RNG rng;
    float a = rng.uniform(0.F, 1.F);
    float b = rng.uniform(0.F, 1.F);
    float c = rng.uniform(0.F, 1.F);
    cout << "a = " << a << ", b = " << b << ", c = " << c << endl;

    double a_d = rng.gaussian(1.0);
    double b_d = rng.gaussian(1.0);
    double c_d = rng.gaussian(1.0);
    cout << "a_d = " << a_d << ", b_d = " << b_d << ", c_d = " << c_d << endl;

    unsigned a_c = rng(255);
    unsigned b_c = rng(255);
    unsigned c_c = rng(255);
    cout << "a_c = " << a_c << ", b_c = " << b_c << ", c_c = " << c_c << endl;

    // 2.
    cv::Vec<float, 20> v1;
    rng.fill(v1, cv::RNG::UNIFORM, 0.0f, 1.0f);
    rng.fill(v1, cv::RNG::NORMAL, 0.0f, 1.0f);
    cv::Vec<uchar, 20> v2;
    rng.fill(v2, cv::RNG::UNIFORM, 0, 255);
    cv::Mat3b v3(20, 1);
    rng.fill(v3, cv::RNG::UNIFORM, 0, 255);

    // 3.
    cv::Mat m3(100, 1, CV_32FC3, cv::Scalar(0));
    // a
    vector<cv::Mat> planes;
    cv::split(m3, planes);
    rng.fill(planes[0], cv::RNG::NORMAL, 64, 10);
    rng.fill(planes[1], cv::RNG::NORMAL, 192, 10);
    // b
    rng.fill(planes[2], cv::RNG::NORMAL, 128, 2);
    // c
    cv::PCA pca(planes[0], cv::Mat(), CV_PCA_DATA_AS_ROW, 2);
    planes[0] = pca.project(planes[0]);

    pca(planes[1], cv::Mat(), CV_PCA_DATA_AS_ROW, 2);
    planes[1] = pca.project(planes[1]);

    pca(planes[2], cv::Mat(), CV_PCA_DATA_AS_ROW, 2);
    planes[2] = pca.project(planes[2]);
    // d
    a = 0;
    b = 0;
    c = 0;
    for(int i = 0; i < 100; i++) {
        a += planes[0].at<float>(i, 0);
        b += planes[1].at<float>(i, 0);
        c += planes[2].at<float>(i, 0);
    }
    a = a / 100;
    b = b / 100;
    c = c / 100;


    // 4.
    cv::Matx32d Ax(1, 1, 0, 1, -1, 1);
    cv::Mat A = static_cast<cv::Mat>(Ax);
    cv::Mat U,W,V;
    cv::SVD::compute(A, W, U, V);



    return 0;
}